package net.maku.project.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import net.maku.api.module.system.SmsApi;
import net.maku.framework.common.exception.ServerException;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.framework.security.user.SecurityUser;
import net.maku.project.convert.ProcessStatesConvert;
import net.maku.project.dao.ProcessStatesDao;
import net.maku.project.dao.StageDao;
import net.maku.project.entity.*;
import net.maku.project.enums.ProcessStatus;
import net.maku.project.query.ProcessStatesQuery;
import net.maku.project.service.*;
import net.maku.project.vo.ProcessStatesVO;
import net.maku.project.vo.StateSelectVO;
import net.maku.project.vo.StatesCountVO;
import net.maku.project.vo.UpdateStateVO;
import net.maku.system.entity.SysRoleEntity;
import net.maku.system.service.SysRoleService;
import net.maku.system.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 流程状态表
 *
 * @author 艾力 1106997025@qq.com
 * @since 1.0.0 2024-07-09
 */
@Service
@AllArgsConstructor
public class ProcessStatesServiceImpl extends BaseServiceImpl<ProcessStatesDao, ProcessStatesEntity> implements ProcessStatesService {


    private ProcessStepsService processStepsService;
    private StepDetailService stepDetailService;

    private final static Integer NEED_CONFIRM_VALUE = 1;

    private final static Integer COMPLETE_VALUE = 1;

    private final static Integer TIMER_START_VALUE = 1;

    private final static String CONFIRM_CONTENT = "已提交相关材料";
    private final static String DISABLED = "此环节已被禁用";
    private final static Integer ENABLE = 0;

    private final static ConcurrentHashMap<Long, String> STEP_NAMES = new ConcurrentHashMap<>();

    private ProcessStagesService processStagesService;

    private ProjectDetailService projectDetailService;

    private SysRoleService sysRoleService;

    private SysUserService sysUserService;

    private SmsApi smsApi;

    private StageDao stageDao;
    private ProcessStatesDao processStatesDao;

    @Override
    public PageResult<ProcessStatesVO> page(ProcessStatesQuery query) {
        IPage<ProcessStatesEntity> page = baseMapper.selectPage(getPage(query), getWrapper());

        return new PageResult<>(ProcessStatesConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    private LambdaQueryWrapper<ProcessStatesEntity> getWrapper() {

        return Wrappers.lambdaQuery();
    }

    @Override
    public void save(ProcessStatesVO vo) {
        ProcessStatesEntity entity = ProcessStatesConvert.INSTANCE.convert(vo);

        baseMapper.insert(entity);
    }

    // 实现了改变流程状态的方法，参数为 ProcessStatesVO 类型的 vo
    @Override
    public void changeStates(ProcessStatesVO vo) {
        // 检查 vo 是否为空或状态信息是否为空，如果是，则抛出 IllegalArgumentException 异常
        if (vo == null || StringUtils.isBlank(vo.getStatus())) {
            throw new IllegalArgumentException("状态信息不能为空");
        }

        // 使用 ProcessStatesConvert 实例将 vo 转换为 ProcessStatesEntity 实体
        ProcessStatesEntity entity = ProcessStatesConvert.INSTANCE.convert(vo);

        // 获取当前用户的 ID
        Long userId = SecurityUser.getUserId();

        // 根据实体的状态获取 ProcessStatus 枚举值
        ProcessStatus status = getProcessStatus(entity.getStatus());

        // 如果状态不是默认状态且存在，则调用 completeState 方法完成状态
        if (status != null && status != ProcessStatus.DEFAULT_STATUS && entity.getStartTime() != null) {
            completeState(entity, userId);
            // 如果开始时间为空，则调用 startState 方法开始状态
        } else if (entity.getStartTime() == null) {
            startState(entity, userId);
            // 否则设置操作者 ID
        } else {
            entity.setOperatorId(userId);
        }

        // 更新 ProcessStatesEntity 实体到数据库
        baseMapper.updateById(entity);
        // 调用 addStepDetail 方法新增环节日志
        addStepDetail(entity);
        //检查是否是分支环节,如果是分支环节（一般同一阶段有两条分支），则更新另一个分支环节的相关信息，如setBranchPath和setStatus
        if (isBranchPoint(entity.getStepId(), entity.getStageId())) {

            // 根据实体的阶段 ID 获取 ProcessStagesEntity 实体
            ProcessStagesEntity stagesEntity = processStagesService.getById(entity.getStageId());

            // 获取配置阶段 ID
            Long configStageId = stagesEntity.getConfigStageId();
            // 假设branchPoints是一个存储所有分支点信息的列表，这里你需要根据实际情况获取或计算分支点信息

            List<Long> branchPoints = processStepsService.getBranchPoints(configStageId);
            //将entity.getId()的值从branchPoints删除
            branchPoints.remove(entity.getStepId());
            //获取branchPoints中id，并根据id查出对应的流程环节，并更新其branchPath和status
            for (Long branchPointId : branchPoints) {
                ProcessStatesEntity branchPoint = new LambdaQueryChainWrapper<>(baseMapper)
                        .eq(ProcessStatesEntity::getStepId, branchPointId)
                        .eq(ProcessStatesEntity::getProjectId, entity.getProjectId())
                        .last("limit 1")
                        .one();
                //更新branchPath
                branchPoint.setBranchPath(1);
                //更新status
                branchPoint.setStatus(DISABLED);
                branchPoint.setCompletionTime(LocalDateTime.now());
                branchPoint.setTimerStarted(0);
                branchPoint.setCompleted(COMPLETE_VALUE);
                branchPoint.setOperatorId(userId);
                baseMapper.updateById(branchPoint);
            }
        }
        // 检查并推进阶段
        checkAndAdvanceStage(entity);

    }

    //新增环节日志
    private void addStepDetail(ProcessStatesEntity entity) {
        StepDetailEntity stepDetailEntity = new StepDetailEntity();
        //获取当前用户的ID
        if (entity.getOperatorId() == null) {
            stepDetailEntity.setCreator("投资方企业");
        }else {
            stepDetailEntity.setCreator(Objects.requireNonNull(SecurityUser.getUser()).getRealName());
        }

        stepDetailEntity.setStepId(entity.getStepId());
        stepDetailEntity.setMatlConfirm(entity.getMatlConfirm());
        stepDetailEntity.setStatus(entity.getStatus());
        stepDetailEntity.setRemark(entity.getRemark());
        stepDetailEntity.setCreateTime(LocalDateTime.now());
        stepDetailEntity.setProjectId(entity.getProjectId());

        stepDetailService.insert(stepDetailEntity);
    }

    // 根据状态字符串获取对应的 ProcessStatus 枚举值
    private ProcessStatus getProcessStatus(String status) {
        for (ProcessStatus s : ProcessStatus.values()) {
            // 遍历枚举值，比较 displayName 是否与状态字符串相等
            if (s.getDisplayName().equals(status)) {
                return s;
            }
        }
        // 如果没有找到匹配项，返回默认状态
        return ProcessStatus.DEFAULT_STATUS;
    }

    // 完成状态的方法，设置完成标志、计时器开始状态、完成时间和操作者 ID
    private void completeState(ProcessStatesEntity entity, Long userId) {
        entity.setCompleted(COMPLETE_VALUE);
        entity.setBranchPath(COMPLETE_VALUE);
        entity.setTimerStarted(0);
        entity.setCompletionTime(LocalDateTime.now());
        entity.setOperatorId(userId);
    }

    // 开始状态的方法，设置开始时间、计时器开始状态、完成状态和操作者 ID
    private void startState(ProcessStatesEntity entity, Long userId) {
        entity.setStartTime(LocalDateTime.now());
        entity.setTimerStarted(TIMER_START_VALUE);
        entity.setCompleted(0);
        entity.setOperatorId(userId);
    }

    // 检查并推进项目阶段的方法
    private void checkAndAdvanceStage(ProcessStatesEntity entity) {
        // 如果已完成标志等于 COMPLETE_VALUE，则检查是否为阶段的最后一步
        if (Objects.equals(entity.getCompleted(), COMPLETE_VALUE)) {
            boolean isLastStep = isLastStepOfStage(entity.getProjectId(), entity.getStageId());
            // 如果是最后一步，更新阶段结束时间并推进项目阶段
            if (isLastStep) {
                processStagesService.updateStageEndTime(entity.getStageId(), LocalDateTime.now());
                advanceProjectStage(entity);
            }
        }
    }

    /**
     * 查询所有正在进行中的流程状态
     *
     * @return 正在进行中的流程状态列表
     */
    @Override
    public List<ProcessStatesEntity> getInProgressStates() {
        // 调用DAO方法获取正在进行中的流程状态
        return processStatesDao.selectInProgressStates();
    }

    // 推进项目阶段至下一状态名称的方法
    private void advanceProjectStage(ProcessStatesEntity entity) {
        // 根据实体的阶段 ID 获取 ProcessStagesEntity 实体
        ProcessStagesEntity stagesEntity = processStagesService.getById(entity.getStageId());

        // 获取配置阶段 ID
        Long configStageId = stagesEntity.getConfigStageId();

        // 如果配置阶段 ID 不为空，则获取下一状态名称并更新项目当前状态
        if (configStageId != null) {
            String nextStatusName = advanceProjectStageToNextStatusName(configStageId);
            processStagesService.updateNextStageStarTime(nextStatusName, stagesEntity.getProjectId());
            projectDetailService.updateProjectCurrentStatus(entity.getProjectId(), nextStatusName);
            //检查是不是完成了所有的阶段
            if (allStageIsCompleted(entity.getProjectId())) {
                projectDetailService.updateProjectEndDate(entity.getProjectId());
            }
        }
    }


    // 检查当前环节是否为最后一个完成的环节
    private boolean isLastStepOfStage(Long projectId, Long stageId) {
        return baseMapper.isAllStepsCompletedInStage(stageId, projectId);
    }

    //检查所有阶段都已完成
    private boolean allStageIsCompleted(Long projectId) {
        return processStagesService.stageIsAllCompleted(projectId);
    }

    // 更新项目信息表的阶段状态到下一个阶段名称
    private String advanceProjectStageToNextStatusName(Long currentStageId) {
        return getNextStageName(currentStageId);
    }


    // 获取下一阶段的名称
    private String getNextStageName(Long currentStageId) {
        return stageDao.getNextStageName(currentStageId);
    }

    private boolean isBranchPoint(Long stepId, Long stageId) {
        // 根据实体的阶段 ID 获取 ProcessStagesEntity 实体
        ProcessStagesEntity stagesEntity = processStagesService.getById(stageId);

        // 获取配置阶段 ID
        Long configStageId = stagesEntity.getConfigStageId();
        // 假设branchPoints是一个存储所有分支点信息的列表，这里你需要根据实际情况获取或计算分支点信息

        List<Long> branchPoints = processStepsService.getBranchPoints(configStageId);
        return branchPoints.contains(stepId);
    }

    @Override
    public void update(ProcessStatesVO vo) {
        Long id = vo.getId();
        ProcessStatesEntity entity1 = baseMapper.selectById(id);
        if (entity1 == null) {
            return;
        }
        baseMapper.update(entity1, new UpdateWrapper<ProcessStatesEntity>().lambda()
                .set(ProcessStatesEntity::getCompleted, 0)
                .set(ProcessStatesEntity::getRemark, null)
                .set(ProcessStatesEntity::getMatlConfirm, "需企业重新确认")
                .set(ProcessStatesEntity::getTimerStarted, 0)
                .set(ProcessStatesEntity::getStartTime, null)
                .set(ProcessStatesEntity::getCompletionTime, null)
                .set(ProcessStatesEntity::getOperatorId, null)
                .set(ProcessStatesEntity::getStatus, "待开始")
                .set(ProcessStatesEntity::getBranchPath, 0)
                .eq(ProcessStatesEntity::getId, id));
        ProcessStatesEntity entity2 = baseMapper.selectById(id);
        System.out.println(entity2);
        addStepDetail(entity2);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

    @Override
    public List<ProcessStatesVO> getProcessStageStates(Long projectId, Long stageId) {
        if (Objects.isNull(projectId) || Objects.isNull(stageId)) {
            return new ArrayList<>();
        }
        // 根据配置阶段 ID 获取 ProcessStagesEntity 实体中实际的阶段ID
        ProcessStagesEntity stagesEntity = processStagesService.getStageByProjectIdAndStageId(projectId, stageId);

        // 获取真正的阶段 ID
        Long realStageId = stagesEntity.getId();
        List<ProcessStatesEntity> statesEntities = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, projectId)
                .eq(ProcessStatesEntity::getStageId, realStageId)
                .list();
        List<ProcessStatesVO> processStatesVOS = ProcessStatesConvert.INSTANCE.convertList(statesEntities);
        processStatesVOS.forEach(vo -> {
            // 获取环节时限
            String deadLine = processStepsService.getDeadLine(vo.getStepId());
            if (!StringUtils.isNotBlank(deadLine) || deadLine.equals("0")) {
                deadLine = "无时限";
            } else {
                deadLine = deadLine + "个工作日内";
            }
            vo.setDeadLine(deadLine);
        });
        return processStatesVOS;
    }

    @Override
    public List<ProcessStatesVO> getProcessStates(Long projectId) {
        if (Objects.isNull(projectId)) {
            return new ArrayList<>();
        }
        List<ProcessStatesEntity> statesEntities = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, projectId)
                .list();
        return ProcessStatesConvert.INSTANCE.convertList(statesEntities);
    }

    @Override
    public List<StateSelectVO> getProcessStatesByProjectId(Long projectId) {
        if (Objects.isNull(projectId)) {
            return new ArrayList<>();
        }
        List<ProcessStepsEntity> processStepsEntityList = processStepsService.list();
        if (CollUtil.isEmpty(processStepsEntityList)) {
            return new ArrayList<>();
        }
        if (STEP_NAMES.size() != processStepsEntityList.size()) {
            processStepsEntityList.forEach(stepEntity -> {
                Long id = stepEntity.getId();
                if (!STEP_NAMES.containsKey(id)) {
                    STEP_NAMES.put(id, stepEntity.getName());
                }
            });
        }
        Set<Long> stepIds = processStepsEntityList.stream().filter(step -> NEED_CONFIRM_VALUE.equals(step.getNeedConfirm())).map(ProcessStepsEntity::getId).collect(Collectors.toSet());
        List<ProcessStatesEntity> processStatesEntities = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, projectId)
                // .ne(ProcessStatesEntity::getCompleted, COMPLETE_VALUE)
                .ne(ProcessStatesEntity::getMatlConfirm, CONFIRM_CONTENT)
                .in(ProcessStatesEntity::getStepId, stepIds)
                .orderByAsc(ProcessStatesEntity::getStepId)
                .list();

        return processStatesEntities.stream().map(step -> {
            StateSelectVO stateSelectVO = new StateSelectVO();
            stateSelectVO.setLabel(STEP_NAMES.get(step.getStepId()));
            stateSelectVO.setValue(step.getStepId());
            return stateSelectVO;
        }).collect(Collectors.toList());

    }

    @Override
    public void updateProcessStates(UpdateStateVO updateStateVO) {
        ProcessStatesEntity statesEntity = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(ProcessStatesEntity::getProjectId, updateStateVO.getProjectId())
                .eq(ProcessStatesEntity::getStepId, updateStateVO.getStepId())
                .last("limit 1")
                .one();
        if (Objects.isNull(statesEntity)) {
            throw new ServerException("数据不存在");
        }
        addStepDetail(statesEntity);
        // 角色
        List<Long> currentHandler = statesEntity.getCurrentHandler();
        if (CollUtil.isNotEmpty(currentHandler)) {
            List<SysRoleEntity> roles = sysRoleService.getRoleByIds(currentHandler);
            if (roles != null && !roles.isEmpty()) {
                // 获取所有角色对应的所有用户ID
                Set<Long> allRoles = roles.stream()
                        .map(SysRoleEntity::getId)
                        .collect(Collectors.toSet());

                // 获取所有用户的手机号
                List<String> allUserMobiles = sysUserService.getUserMobilesByRoleIds(new ArrayList<>(allRoles));
                // 按角色分类手机号
                List<String> countyLeadersMobiles = new ArrayList<>();
                List<String> branchLeadersMobiles = new ArrayList<>();
                List<String> staffsMobiles = new ArrayList<>();
                String dept = "--";
                for (SysRoleEntity role : roles) {
                    Long roleId = role.getId();
                    String roleCode = role.getRoleCode();

                    if (!"SFX_LEADER".equals(roleCode)) {
                        if (roleCode.endsWith("_LEADER")) {
                            branchLeadersMobiles.addAll(allUserMobiles.stream()
                                    .filter(mobile -> Objects.nonNull(mobile) && allRoles.contains(roleId))
                                    .toList());
                        } else {
                            staffsMobiles.addAll(allUserMobiles.stream()
                                    .filter(mobile -> Objects.nonNull(mobile) && allRoles.contains(roleId))
                                    .toList());
                            dept = "【" + role.getName() + "】";
                        }
                    }
//                        countyLeadersMobiles.addAll(allUserMobiles.stream()
//                                .filter(mobile -> Objects.nonNull(mobile) && allRoles.contains(roleId))
//                                .toList());
                    //啥也不干


                }

                // 发送短信
                InfoEntity infoEntity = projectDetailService.getById(updateStateVO.getProjectId());
                if (infoEntity != null) {
                    Map<String, String> params = new HashMap<>();
                    params.put("companyName", removeSuffix(infoEntity.getInvestorName(), new String[]{"公司"}));
                    params.put("projectName", removeSuffix(infoEntity.getProjectName(), new String[]{"项目"}));
                    params.put("department", dept);
                    params.put("procedure", processStepsService.getNameById(statesEntity.getStepId()));
                    params.put("days", processStepsService.getDeadLine(statesEntity.getStepId()));
                    params.put("contact", infoEntity.getContactName());
                    params.put("contactMobile", infoEntity.getContactPhone());

                    String linkedLeader = infoEntity.getLinkedLeaderPhone();
                    if (StringUtils.isNotEmpty(linkedLeader)) {
                        countyLeadersMobiles.add(linkedLeader);
                    }
                    sendSmsWithTemplate(countyLeadersMobiles, params, "C");
                    sendSmsWithTemplate(branchLeadersMobiles, params, "B");
                    sendSmsWithTemplate(staffsMobiles, params, "A");
                }
            }
        }

        statesEntity.setMatlConfirm(CONFIRM_CONTENT);
        statesEntity.setStartTime(LocalDateTime.now());
        statesEntity.setBranchPath(ENABLE);
        statesEntity.setTimerStarted(TIMER_START_VALUE);
        baseMapper.updateById(statesEntity);
    }

    @Override
    public List<StatesCountVO> getStatesCount() {

        List<ProcessStatesEntity> states = new LambdaQueryChainWrapper<>(baseMapper).list();
        List<Object[]> stepInfos = processStepsService.getAllStepDeadLine();


        if (CollUtil.isEmpty(states)) {
            return new ArrayList<>();
        }

        Map<Long, Object[]> stepInfoMap = new HashMap<>();

        for (Object[] info : stepInfos) {
            Long stepId = (Long) info[0];
            stepInfoMap.put(stepId, info);
        }

        List<StatesCountVO> result = new ArrayList<>();
        Set<String> stepNames = stepInfoMap.values().stream()
                .map(info -> (String) info[1])
                .collect(Collectors.toSet());

        Map<String, Long> stepNameToIdMap = new HashMap<>();
        for (Map.Entry<Long, Object[]> entry : stepInfoMap.entrySet()) {
            Object[] info = entry.getValue();
            String stepName = (String) info[1];
            stepNameToIdMap.put(stepName, entry.getKey()); // 将步骤名称映射到步骤 ID
        }



        for (String stepName : stepNames) {
            Long id = stepNameToIdMap.get(stepName); // 通过映射直接获取步骤 ID

            StatesCountVO vo = new StatesCountVO();
            vo.setId(id);
            vo.setStepName(stepName);
            vo.setTimeoutsCount(0);
            vo.setBeingProcessedCount(0);
            vo.setAverageDuration("0天0时0分");
            result.add(vo);
        }

        // 统计每个步骤下已完成的总时长和已完成任务的数量，用于计算平均时长
        Map<String, Long> completedTaskCounts = new HashMap<>();
        Map<String, Duration> totalDurations = new HashMap<>();
// 遍历所有的状态实体，进行统计
        for (ProcessStatesEntity state : states) {
            Long stepId = state.getStepId();
            Object[] stepInfo = stepInfoMap.get(stepId);
            if (stepInfo != null) {
                String stepName = (String) stepInfo[1];
                Integer deadline = (Integer) stepInfo[2];

                if (deadline > 0) {
                    boolean isTimeout = state.getTimerStarted() == 1 && isOverDeadline(state.getStartTime(), deadline);
                    if (isTimeout) {
                        updateStateCount(result, stepName, true);
                    }
                }

                if (state.getTimerStarted() == 1) {
                    updateStateCount(result, stepName, false);
                }

                if (state.getCompleted() == 1) {
                    Duration duration = Duration.between(state.getStartTime(), state.getCompletionTime());
                    totalDurations.merge(stepName, duration, Duration::plus);
                    completedTaskCounts.merge(stepName, 1L, Long::sum);
                }
            }
        }

// 计算平均时长
        // 计算平均时长
        for (StatesCountVO vo : result) {
            Duration totalDuration = totalDurations.get(vo.getStepName());
            long completedTasks = completedTaskCounts.getOrDefault(vo.getStepName(), 0L);
            if (completedTasks > 0) {
                Duration averageDuration = totalDuration.dividedBy(completedTasks);
                vo.setAverageDuration(formatDuration(averageDuration));
            }
        }

        // 在返回结果前，根据 id 字段对 result 列表进行升序排序
        result = result.stream()
                .sorted(Comparator.comparing(StatesCountVO::getId))
                .collect(Collectors.toList());
        return result;

    }

    @Override
    public float getProgressPercentageByProjectId(Long id) {
        // 查询当前项目环节中所有已完成环节的数量并与所有环节数量进行比较，得出百分比进度
        List<ProcessStatesEntity> states_Completed = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, id)
                .eq(ProcessStatesEntity::getCompleted, 1)
                .list();
        List<ProcessStatesEntity> states_All = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, id)
                .list();
        if (states_All.size() == 0) {
            return 0;
        }
        // 计算百分比进度, 返回结果保留1位小数
        float percentage = ((float) states_Completed.size() / states_All.size()) * 100;

        return (float) Math.round(percentage * 10) / 10;
    }

    @Override
    public boolean getIsOverdueStates(Long id) {
        // 查询当前项目环节中所有开启计时器的环节是否有逾期环节
        List<ProcessStatesEntity> states_TimerStarted = new LambdaQueryChainWrapper<>(baseMapper).eq(ProcessStatesEntity::getProjectId, id)
                .eq(ProcessStatesEntity::getTimerStarted, 1)
                .list();
        List<Object[]> stepInfos = processStepsService.getAllStepDeadLine();

        if (states_TimerStarted.isEmpty()) {
            return false;
        }
        Map<Long, Object[]> stepInfoMap = new HashMap<>();

        for (Object[] info : stepInfos) {
            Long stepId = (Long) info[0];
            stepInfoMap.put(stepId, info);
        }
        for (ProcessStatesEntity state : states_TimerStarted) {
            Object[] stepInfo = stepInfoMap.get(state.getStepId());
            if (stepInfo != null) {
                Integer deadline = (Integer) stepInfo[2];
                if (deadline > 0 && isOverDeadline(state.getStartTime(), deadline)) {
                    return true;
                }
            }
        }
        return false;
    }

    // 辅助函数，判断是否超过时限
    private boolean isOverDeadline(LocalDateTime startTime, int deadline) {
        LocalDateTime deadlineTime = startTime.plusHours(deadline);
        return LocalDateTime.now().isAfter(deadlineTime);
    }


    // 更新或创建 StatesCountVO 对象
    private void updateStateCount(List<StatesCountVO> result, String stepName, boolean isTimeout) {
        StatesCountVO vo = result.stream()
                .filter(item -> item.getStepName().equals(stepName))
                .findFirst()
                .orElseGet(() -> {
                    StatesCountVO newVo = new StatesCountVO();
                    newVo.setStepName(stepName);
                    newVo.setTimeoutsCount(0);
                    newVo.setBeingProcessedCount(0);
                    newVo.setAverageDuration("0天0时0分");
                    result.add(newVo);
                    return newVo;
                });

        if (isTimeout) {
            vo.setTimeoutsCount(vo.getTimeoutsCount() + 1);
        } else {
            vo.setBeingProcessedCount(vo.getBeingProcessedCount() + 1);
        }
    }

    // 格式化持续时间
    private String formatDuration(Duration duration) {
        long days = duration.toDays();
        long hours = duration.minusDays(days).toHours();
        long minutes = duration.minusDays(days).minusHours(hours).toMinutes();
        return String.format("%d天%d时%d分", days, hours, minutes);
    }
    // 辅助方法发送短信

    private void sendSmsWithTemplate(List<String> mobiles, Map<String, String> params, String templateId) {
        if (mobiles != null && !mobiles.isEmpty()) {
            for (String mobile : mobiles) {
                params.put("templateId", templateId);
                smsApi.send(mobile, params);
            }
        }
    }

    // 定义一个方法，用于移除字符串末尾的特定词汇
    public static String removeSuffix(String str, String[] suffixes) {
        if (str == null || str.isEmpty() || suffixes == null) {
            return str;
        }

        for (String suffix : suffixes) {
            if (str.endsWith(suffix)) {
                return str.substring(0, str.length() - suffix.length());
            }
        }
        return str;
    }
}